package com.yf.cl.initializaton;

/*
 类加载过程：loading(加载)->linking连接(verification验证->preparation准备->resolution解析)
 ->initialization初始化->using使用-unloading卸载

 初始化阶就是执行类构造器方法clinit()的过程
 此方法不需要定义，由javac编译器自动收集集中的所有类变量的赋值动作和静态代码块中的语句合并而来。
 构造器方法中指令按语句在源文件中出现的顺序执行
 clinit()不同于类的构造。（构造器是虚拟机视角下的init()）
 若该类具有父类，JVM会保证子类的clinit()执行前，父类的clinit已经执行完毕
 虚拟机必须保证一个类的clinit()方法在多线程下被同步加锁

 当类中没有静态变量，常量及静态代码块字节码文件中就不会生成clinit方法
 */
public class ClinitTest {
    /*
     任何一个类声明以后，内部至少存在一个类的构造器。
     当没有显示声明构造方法时，默认会自动添加一个无参构造方法。
     */
    private static double PI = 3.14;

    static {
        PI = 3.1415;
        // n可以在此赋值
        n = 20;
        // n不可以在此调用
        // System.out.println(n);
    }

    private static int n = 10; //1.linking(prepare)阶段n = 0; 2.initial: 先赋值20 -> 再赋值10

    public static void main(String[] args) {
        int i = 2 + 3;
        System.out.println(PI); // 3.1415
        System.out.println(n); // 10
    }
}
